package com.xiaotu.storage.converter;

import java.math.BigDecimal;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.util.MathUtil;
import com.xiaotu.common.util.RegexUtils;

import net.sf.json.JSONObject;

/**
 * @类名 NumberFormateConverter
 * @日期 2017年2月21日
 * @作者 高海军
 * @功能 数值格式转换器
 */
@Component("NumberFormateConverter")
public class NumberFormateConverter extends AConverter
{
	private static final Logger LOGGER = LoggerFactory
			.getLogger(NumberFormateConverter.class);
	
	private static final String UNIT_REGX = "千|万|亿";// 数值单位正则
	
	private static final BigDecimal MIN_VALUE = new BigDecimal(1000);
	
	@Override
	protected Object doConvert(String value, JSONObject target,
			boolean needThrow)
	{
		value = value.replace(",", StringUtils.EMPTY);
		return this.unitProcess(value, needThrow);
	}
	
	private Object unitProcess(String value, boolean needThrow)
	{
		if (RegexUtils.regexMatch(RegexUtils.REGEX_E_NOTATION, value))
			return new BigDecimal(value);
		String unit = RegexUtils.regexSearch(UNIT_REGX, value);
		value = RegexUtils.replaceStr(value, UNIT_REGX, StringUtils.EMPTY);
		if(StringUtils.isBlank(value)){
			value = "0";
		}
		boolean isNumeric = RegexUtils.regexMatch(RegexUtils.REGEX_NUMBER,
				value);
		if (!isNumeric && needThrow)
			throw new SpiderException(
					SpiderExceptionCode.NumberFormateException,
					"value:" + value);
		else if (!isNumeric)
		{
			LOGGER.warn("value is not numeric:" + value);
			return value;
		}
		BigDecimal val = new BigDecimal(value);
		if (StringUtils.isNotEmpty(unit))
			switch (unit)
			{
				case "千":
					val = MathUtil.mul(val, 1000);
					break;
				case "万":
					val = MathUtil.mul(val, 10000);
					break;
				case "亿":
					val = MathUtil.mul(val, 100000000);
					break;
				default:
					break;
			}
		if (val.compareTo(MIN_VALUE) < 0)
			return val;
		return val;
	}
}
